﻿using AutoMapper;
using ImoviesBlazor.Server.Helpers;
using ImoviesBlazor.Server.Repository;
using ImoviesBlazor.Shared.Dtos;
using ImoviesBlazor.Shared.Entities;
using ImoviesBlazor.Shared.Utils;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using System.Security.Cryptography;
using System.Text;

namespace ImoviesBlazor.Server.Controllers
{

    /// <summary>
    /// 电影控制器
    /// </summary>
    [ApiController]
    [Route("api/[controller]")]
    public class MovieController : ControllerBase
    {
        private readonly IMovieRepository _movieRepository;
        private readonly IMapper _mapper;

        public MovieController(IMovieRepository movieRepository, IMapper mapper)
        {
            this._movieRepository = movieRepository;
            this._mapper = mapper;
        }


        /// <summary>
        /// 获取所有年份
        /// </summary>
        /// <returns></returns>
        [HttpGet("years")]
        public async Task<ActionResult<IEnumerable<uint>>> GetAllYears()
        {
            // 先从缓存中读取
            var cacheYears = CacheUtils.GetData<List<uint>>(CacheKeyConst.MOVIE_ALL_YEARS);
            if (cacheYears != null)
            {
                return Ok(cacheYears);
            }

            var years = await _movieRepository.GetAllYearsAsync();

            // 设置缓存
            CacheUtils.SetData<List<uint>>(CacheKeyConst.MOVIE_ALL_YEARS, years.Distinct().ToList());

            return Ok(years.Distinct());
        }


        /// <summary>
        /// 分页获取数据
        /// </summary>
        /// <param name="pageSize">页大小</param>
        /// <param name="pageNum">页码</param>
        /// <returns></returns>
        [HttpGet]
        public async Task<ActionResult<IEnumerable<MovieDataList>>> GetList([FromQuery] int pageSize, [FromQuery] int pageNum)
        {
            string cacheKey = $"{CacheKeyConst.MOVIE_PAGINATION_LIST}{pageSize}{pageNum}";
            // 先从缓存中读取
            var cacheData = CacheUtils.GetData<PaginationList<MovieDataList>>(cacheKey);
            if (cacheData != null)
            {
                return Ok(cacheData);
            }

            var ms = await _movieRepository.GetListAsync(pageSize, pageNum);

            var msDtolist = _mapper.Map<IEnumerable<MovieDto>>(ms);
            List<MovieDataList> list = new List<MovieDataList>();
            var gy = msDtolist.GroupBy(x => x.Year).ToList();

            foreach (var item in gy)
            {
                list.Add(new MovieDataList
                {
                    Year = item.Key,
                    List = item.ToList()
                });
            }

            var total = await _movieRepository.GetTotal();
            var data = new PaginationList<MovieDataList>
            {
                Data = list,
                Total = total,
            };

            // 设置缓存
            CacheUtils.SetData<PaginationList<MovieDataList>>(cacheKey, data);

            return Ok(data);
        }


        /// <summary>
        /// 获取所有视频列表
        /// </summary>
        /// <returns></returns>
        [HttpGet("all")]
        public async Task<ActionResult<IEnumerable<MovieDataList>>> GetAll()
        {
            // 先从缓存中读取
            var cacheData = CacheUtils.GetData<List<MovieDto>>(CacheKeyConst.MOVIE_ALL_LIST);
            if (cacheData != null)
            {
                return Ok(cacheData);
            }

            var list = await _movieRepository.GetAllListAsync();
            var msDtoList = _mapper.Map<IEnumerable<MovieDto>>(list);

            // 设置缓存
            CacheUtils.SetData<List<MovieDto>>(CacheKeyConst.MOVIE_ALL_LIST, msDtoList.ToList());

            return Ok(msDtoList);
        }


        /// <summary>
        /// 获取视频链接列表
        /// </summary>
        /// <param name="vid"></param>
        /// <returns></returns>
        [HttpGet("vlist/{vid}")]
        public async Task<ActionResult<IEnumerable<MovieVlinkDto>>> GetVlinkList(string vid)
        {
            string cacheKey = $"{CacheKeyConst.MOVIE_PLAYLINK_LIST}{vid}";
            // 先从缓存中读取
            var cacheData = CacheUtils.GetData<List<MovieVlinkDto>>(cacheKey);
            if (cacheData != null)
            {
                return Ok(cacheData);
            }

            var vlinks = await _movieRepository.GetVlinkList(vid);
            var data = _mapper.Map<IEnumerable<MovieVlinkDto>>(vlinks);

            // 设置缓存
            CacheUtils.SetData<List<MovieVlinkDto>>(cacheKey, data.ToList());

            return Ok(data);
        }



        /// <summary>
        /// 添加
        /// </summary>
        /// <param name="movie"></param>
        /// <returns></returns>
        [Authorize]
        [HttpPost]
        public async Task<ActionResult> AddMovie([FromBody] MovieForCreateDto movie)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest();
            }
            var m = _mapper.Map<Movie>(movie);
            byte[] bytes = MD5.HashData(Encoding.UTF8.GetBytes(movie.Name));
            m.Id = BitConverter.ToString(bytes).Replace("-", "");
            _movieRepository.AddMovie(m);
            bool res = await _movieRepository.SaveAsync();
            if (!res)   //保存失败
            {
                Response.StatusCode = 500;
                return Content("操作失败");
            }
            return Ok();
        }


        /// <summary>
        /// 修改
        /// </summary>
        /// <param name="movie"></param>
        /// <returns></returns>
        [Authorize]
        [HttpPut]
        public async Task<ActionResult> UpdateMovie([FromBody] MovieForUpdateDto movie)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest();
            }
            var t = _mapper.Map<Movie>(movie);
            _movieRepository.UpdateMovie(t);
            bool res = await _movieRepository.SaveAsync();
            if (!res)   //保存失败
            {
                Response.StatusCode = 500;
                return Content("操作失败");
            }
            return Ok();
        }

        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [Authorize]
        [HttpDelete("{id}")]
        public async Task<ActionResult<bool>> DeleteTeleplay([FromRoute] string id)
        {
            await _movieRepository.DeleteMovie(id);
            bool res = await _movieRepository.SaveAsync();
            if (!res)   //保存失败
            {
                Response.StatusCode = 500;
                return Content("操作失败");
            }
            return Ok();
        }
    }
}
